/* @(#)FseDocumentSectionHistory.java
** 
** Copyright (C) 2012 by Steven D. Stamps
**
**             Trademarks & Copyrights
** Flywheel Management Science(TM), Flywheel Management Model(TM),
** Flywheel Story Editor(TM) and FlywheelMS(TM) are exclusive trademarks
** of Steven D. Stamps and may only be used freely for the purpose of
** identifying the unforked version of this software.  Subsequent forks
** may not use these trademarks.  All other rights are reserved.
**
** DecKanGL (Decorated Kanban Glyph Language) and TribKn (Tribal Knowledge)
** are also exclusive trademarks of Steven D. Stamps.  These may be used
** freely within the unforked FlywheelMS application and documentation.
** All other rights are reserved.
**
** gConGUI (game Controller Graphical User Interface) is an exclusive
** trademark of Steven D. Stamps.  This trademark may be used freely
** within the unforked FlywheelMS application and documentation.
** All other rights are reserved.
**
** Trademark information is available at
** <http://www.flywheelms.com/trademarks>
**
** Flywheel Management Science(TM) is a copyrighted body of management
** metaphors, governance processes, and leadership techniques that is
** owned by Steven D. Stamps.  These copyrighted materials may be freely
** used, without alteration, by the community (users and developers)
** surrounding this GPL3-licensed software.  Additional copyright
** information is available at <http://www.flywheelms.org/copyrights>
**
**              GPL3 Software License
** This program is free software: you can use it, redistribute it and/or
** modify it under the terms of the GNU General Public License, version 3,
** as published by the Free Software Foundation. This program is distributed
** in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
** even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
** PURPOSE.  See the GNU General Public License for more details. You should
** have received a copy of the GNU General Public License, in a file named
** COPYING, along with this program.  If you cannot find your copy, see
** <http://www.gnu.org/licenses/gpl-3.0.html>.
*/

package com.flywheelms.library.fse.model;

import java.util.ArrayList;
import java.util.Date;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.flywheelms.library.fca.FlywheelCommunityAuthentication;
import com.flywheelms.library.fca.util.FcaUserCredentials;
import com.flywheelms.library.fmm.serialization.FseDocumentSerialization;
import com.flywheelms.library.fse.FseDocumentSectionType;
import com.flywheelms.library.fse.enumerator.FseHistoryCompression;

public class FseDocumentSectionHistory extends FseDocumentSection {
	
	private FseHistoryCompression historyCompression = FseHistoryCompression.NONE;
	private ArrayList<FseDocumentTransaction> documentTransactionList = new ArrayList<FseDocumentTransaction>();
	
	public FseDocumentSectionHistory() {
		super(FseDocumentSectionType.HISTORY);
	}
	
	public FseDocumentSectionHistory(JSONObject aJsonObject) {
		super(FseDocumentSectionType.HISTORY);
		try {
			this.historyCompression = FseHistoryCompression.getObjectForName(aJsonObject.getString(FseDocumentSerialization.key__DOCUMENT_SECTION__HISTORY_COMPRESSION));
			JSONArray theJsonArray = aJsonObject.getJSONArray(FseDocumentSerialization.key__TRANSACTION_LIST);
			for(int i=0;i < theJsonArray.length();i++){                                     
				JSONObject theTransactionJsonObject = theJsonArray.getJSONObject(i);
				this.documentTransactionList.add(new FseDocumentTransaction(theTransactionJsonObject));
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}         
	}

	@Override
	public String getSerialized() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public JSONObject getJsonObject() {
		JSONObject theJsonObject = new JSONObject();
		try {
			theJsonObject.put(FseDocumentSerialization.key__DOCUMENT_SECTION__HISTORY_COMPRESSION, this.historyCompression.getName());
			JSONArray theJsonArray = new JSONArray();
			for (FseDocumentTransaction theDocumentTransaction : this.documentTransactionList) {
				theJsonArray.put(theDocumentTransaction.getJsonObject());
			}
			theJsonObject.put(FseDocumentSerialization.key__TRANSACTION_LIST, theJsonArray);
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return theJsonObject;
	}
	
	public ArrayList<FseDocumentTransaction> getDocumentTransactionList() {
//		if(this.documentTransactionList.size() == 0) {
//			generateTestData();
//		}
		return this.documentTransactionList;
	}

	private void generateTestData() {
//		FseDocumentTransaction theDocumentTransaction = ;
//		theDocumentTransaction.set
		FseDocumentSectionParagraphAudit theStoryBodyAudit = new FseDocumentSectionParagraphAudit(FseDocumentSectionType.STORY);
		theStoryBodyAudit.setParagraphsDeletedCount(1);
		theStoryBodyAudit.setParagraphsLockedCount(3);
		theStoryBodyAudit.setParagraphsModifiedCount(4);
		theStoryBodyAudit.setParagraphsNewCount(2);
		theStoryBodyAudit.setParagraphsUnchangedCount(5);
		FseDocumentSectionParagraphAudit theNotesBodyAudit = new FseDocumentSectionParagraphAudit(FseDocumentSectionType.NOTES);
		theNotesBodyAudit.setParagraphsLockedCount(1);
		theNotesBodyAudit.setParagraphsModifiedCount(6);
		theNotesBodyAudit.setParagraphsNewCount(3);
		theNotesBodyAudit.setParagraphsUnchangedCount(2);
		this.documentTransactionList.add(new FseDocumentTransaction(
				1,
				new Date(),
				FseDocumentTransactionType.CREATE,
				"Adam Dye",
				theStoryBodyAudit,
				theNotesBodyAudit,
				"water cooler with Bill",
				"" ));
		theStoryBodyAudit = new FseDocumentSectionParagraphAudit(FseDocumentSectionType.STORY);
		theStoryBodyAudit.setParagraphsModifiedCount(4);
		theStoryBodyAudit.setParagraphsNewCount(2);
		theStoryBodyAudit.setParagraphsUnchangedCount(8);
		theNotesBodyAudit = new FseDocumentSectionParagraphAudit(FseDocumentSectionType.NOTES);
		theNotesBodyAudit.setParagraphsDeletedCount(1);
		theNotesBodyAudit.setParagraphsModifiedCount(4);
		theNotesBodyAudit.setParagraphsNewCount(2);
		theNotesBodyAudit.setParagraphsUnchangedCount(7);
		this.documentTransactionList.add(new FseDocumentTransaction(
				2,
				new Date(),
				FseDocumentTransactionType.MODIFY,
				"Steve Stamps",
				theStoryBodyAudit,
				theNotesBodyAudit,
				"Collaborate with Adam",
				"" ));
		theStoryBodyAudit = new FseDocumentSectionParagraphAudit(FseDocumentSectionType.STORY);
		theStoryBodyAudit.setParagraphsModifiedCount(2);
		theStoryBodyAudit.setParagraphsNewCount(1);
		theStoryBodyAudit.setParagraphsUnchangedCount(13);
		theNotesBodyAudit = new FseDocumentSectionParagraphAudit(FseDocumentSectionType.NOTES);
		theNotesBodyAudit.setParagraphsNewCount(1);
		theNotesBodyAudit.setParagraphsUnchangedCount(17);
		this.documentTransactionList.add(new FseDocumentTransaction(
				3,
				new Date(),
				FseDocumentTransactionType.MODIFY,
				"Adam Dye",
				theStoryBodyAudit,
				theNotesBodyAudit,
				"Collaborate with Jon",
				"" ));
		theStoryBodyAudit = new FseDocumentSectionParagraphAudit(FseDocumentSectionType.STORY);
		theStoryBodyAudit.setParagraphsDeletedCount(1);
		theStoryBodyAudit.setParagraphsLockedCount(4);
		theStoryBodyAudit.setParagraphsModifiedCount(8);
		theStoryBodyAudit.setParagraphsNewCount(4);
		theStoryBodyAudit.setParagraphsUnchangedCount(4);
		theStoryBodyAudit.setParagraphsUnlockedCount(1);
		theNotesBodyAudit = new FseDocumentSectionParagraphAudit(FseDocumentSectionType.NOTES);
		theNotesBodyAudit.setParagraphsDeletedCount(0);
		theNotesBodyAudit.setParagraphsModifiedCount(6);
		theNotesBodyAudit.setParagraphsNewCount(9);
		theNotesBodyAudit.setParagraphsUnchangedCount(2);
		this.documentTransactionList.add(new FseDocumentTransaction(
				4,
				new Date(),
				FseDocumentTransactionType.MODIFY,
				"Jon Haarmann",
				theStoryBodyAudit,
				theNotesBodyAudit,
				"First stakeholder meeting",
				"" ));
		theStoryBodyAudit = new FseDocumentSectionParagraphAudit(FseDocumentSectionType.STORY);
		theStoryBodyAudit.setParagraphsModifiedCount(6);
		theStoryBodyAudit.setParagraphsNewCount(2);
		theStoryBodyAudit.setParagraphsUnchangedCount(14);
		theNotesBodyAudit = new FseDocumentSectionParagraphAudit(FseDocumentSectionType.NOTES);
		theNotesBodyAudit.setParagraphsLockedCount(6);
		theNotesBodyAudit.setParagraphsModifiedCount(7);
		theNotesBodyAudit.setParagraphsNewCount(2);
		theNotesBodyAudit.setParagraphsUnchangedCount(12);
		this.documentTransactionList.add(new FseDocumentTransaction(
				5,
				new Date(),
				FseDocumentTransactionType.MODIFY,
				"Steve Stamps",
				theStoryBodyAudit,
				theNotesBodyAudit,
				"Collab with Adam & Jon",
				"" ));
		theStoryBodyAudit = new FseDocumentSectionParagraphAudit(FseDocumentSectionType.STORY);
		theStoryBodyAudit.setParagraphsLockedCount(9);
		theStoryBodyAudit.setParagraphsModifiedCount(6);
		theStoryBodyAudit.setParagraphsNewCount(1);
		theStoryBodyAudit.setParagraphsUnchangedCount(16);
		theNotesBodyAudit = new FseDocumentSectionParagraphAudit(FseDocumentSectionType.NOTES);
		theNotesBodyAudit.setParagraphsModifiedCount(4);
		theNotesBodyAudit.setParagraphsNewCount(3);
		theNotesBodyAudit.setParagraphsUnchangedCount(13);
		this.documentTransactionList.add(new FseDocumentTransaction(
				6,
				new Date(),
				FseDocumentTransactionType.LOCK,
				"Jon Haarmann",
				theStoryBodyAudit,
				theNotesBodyAudit,
				"Final stakeholder meeting",
				"" ));
		
	}

	public FseDocumentSectionHistory getClone() {
		return new FseDocumentSectionHistory(this.getJsonObject());
	}
	
	public int getLatestTransactionNumber() {
		return this.documentTransactionList.size();
	}

	public void updateHistory(
			Date aTimestamp,
			FseDocumentTransactionType aDocumentTransactionType,
			FseDocumentSectionParagraphAudit aStoryAudit,
			FseDocumentSectionParagraphAudit aNotesAudit,
			FseDocument aBaselineFseDocument ) {
		// TODO - implement compression, based upon the value of this.historyCompression
		this.documentTransactionList.add(new FseDocumentTransaction(
				getLatestTransactionNumber() + 1,
				aTimestamp,
				aDocumentTransactionType,
				FlywheelCommunityAuthentication.getInstance().getFcaUserCredentials().getFcaUserId(),
				aStoryAudit,
				aNotesAudit,
				"",
				aBaselineFseDocument.getSerialized() ));
	}

}
